home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Application.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-10
|
10KB
|
457 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Application.h"
#include "Document.h"
#include "Class.h"
#include "Storage.h"
#include "FileDialog.h"
#include "ObjectTable.h"
#include "ClassManager.h"
#include "ClipBoard.h"
#include "ProgEnv.h"
#include "Buttons.h"
#include "StreamConnection.h"
#include "WindowSystem.h"
#include "Env.h"
#include "ProgressDialog.h"
#include "Data.h"
#include "Alert_e.h"
#include "Error.h"
#include "Menu.h"
#include "String.h"
#include "Expander.h"
#include "MenuBar.h"
#include "DebuggerIF.h"
StreamConnection *gRpc;
Application *gApplication;
ClipBoard *gClipBoard;
int gArgc;
char **gArgv;
extern char *gProgPath;
//---- AppRpcConnection --------------------------------------------------------
class AppRpcConnection : public StreamConnection {
public:
MetaDef(AppRpcConnection);
AppRpcConnection() : StreamConnection(-1)
{ Open(gSystem->OpenConnection(SERVERNAME, SERVICENAME));
Talk(0, "enroll", gProgname); }
~AppRpcConnection()
{ SendTo(0, "remove", gProgname); }
void Dispatch(int from, char *req, char *buf, int len, char *&ret, int &retlen)
{ gApplication->ExtCommand(from, req, buf, len, ret, retlen);
gWindowSystem->Update(); }
};
NewMetaImpl0(AppRpcConnection,StreamConnection);
//---- ApplIntHandler ----------------------------------------------------------
class ApplIntHandler : public SysEvtHandler {
public:
MetaDef(ApplIntHandler);
ApplIntHandler() : SysEvtHandler(eSigInterrupt)
{ }
void Notify(SysEventCodes, int)
{ if (gApplication) gApplication->Inspect(); }
};
NewMetaImpl0(ApplIntHandler,SysEvtHandler);
//---- ApplErrorHandler --------------------------------------------------------
static void ApplErrorHandler(int level, bool, char *location, char *msg)
{
gApplication->DoOnError(level, location, msg);
}
//---- Application -------------------------------------------------------------
NewAbstractMetaImpl(Application,Manager, (T(lastWindowPos), TS(version),
T(mainDocumentType), TP(fileDialog), TP(gApplication), TP(gClipBoard),
TVP(gArgv,gArgc), TP(gClassManager)));
FileDialog *Application::fileDialog;
Application::Application(int ac, char **av, Symbol &dt)
{
if (gApplication)
Error("Application", "only one Application !!");
gApplication= this;
version= "Version 3.0, 7/1/92, \251IFI & UBS-UBILAB";
gArgc= ac;
gArgv= av;
mainDocumentType= dt;
ETInit(gArgv);
SetName(ProgramName());
WindowSystem::WSInit();
SetErrorHandler(ApplErrorHandler);
lastWindowPos= Point(150, 100);
char *cp= Env::GetValue("Document.Position", (char*)0);
if (cp) {
IStream is(strlen(cp), cp);
is >> lastWindowPos;
}
}
Application::~Application()
{
if (gApplication == this)
gApplication= 0;
SafeDelete(fileDialog);
}
char *Application::GetName()
{
return gProgname;
}
FileDialog *Application::MakeFileDialog()
{
return new FileDialog;
}
void Application::NewManager(Symbol type)
{
Manager *mp= DoMakeManager(type); // let user make his managers
if (mp) {
AddManager(mp);
mp->Show();
}
}
void Application::ParseCommandLine(int argc, char **argv)
{
for (int i= 1; i < argc;) {
if (argv[i][0] == '-') {
int n= DoParseOptions(argv[i], argv[i+1]);
if (n > 0)
i+= n;
else
i++;
} else
OpenDocument(argv[i++]);
}
}
int Application::DoParseOptions(char *arg0, char*)
{
if (arg0[0] == '-' && arg0[1] == 'E') {
if (arg0[2] == 'e')
gProgEnv->Start();
if (arg0[2] == 'h')
gProgEnv->ShowInHierarchy(this->IsA());
return 1;
}
return 0;
}
void Application::RemoveManager(Manager *mp)
{
Manager::RemoveManager(mp);
if (Size() <= 0 && !IsOpen())
Quit();
}
char *Application::ProgramName()
{
return BaseName(gProgname);
}
Point Application::GetInitialWindowPos()
{
return GetNewDocumentPos();
}
void Application::About()
{
ShowAlert(eAlertSun, "%s %s", ProgramName(), version);
}
Command *Application::DoMenuCommand(int cmd)
{
switch(cmd) {
case cNEW:
NewManager(mainDocumentType);
break;
case cQUIT:
Quit();
break;
case cABOUT:
About();
break;
case cOPEN:
OpenDocument(0);
break;
default:
Manager::DoMenuCommand(cmd);
break;
}
return gNoChanges;
}
void Application::DoSetupMenu(Menu *m)
{
Manager::DoSetupMenu(m);
m->EnableItems(cOPEN, cNEW, cQUIT, cABOUT, 0);
}
void Application::Control(int id, int part, void *val)
{
SendDown(id, part, val);
}
void Application::ExtCommand(int from, char *rq, char *args, int len,
char *&ret, int &retlen)
{
char req[100];
strcpy(req, rq);
if (strcmp(req, "remove") == 0) {
gWindowSystem->ExtCommand(from, req, args, len, ret, retlen);
return;
}
char *cp= strchr(req, ':');
if (cp) {
*cp++= 0;
if (strcmp(req, "clipboard") == 0)
gWindowSystem->ExtCommand(from, cp, args, len, ret, retlen);
else if (strcmp(req, "document") == 0) {
Iter next(MakeIterator());
Manager *first= (Manager*)next();
if (first)
first->ExtCommand(from, cp, args, len, ret, retlen);
} else if (strcmp(req, "application") == 0) {
if (strcmp(cp, "quit") == 0)
Quit();
else if (strcmp(cp, "about") == 0)
About();
else if (strcmp(cp, "new") == 0)
NewManager(mainDocumentType);
else if (strcmp(cp, "open") == 0)
OpenDocument(args);
else if (strcmp(cp, "inspect") == 0)
Inspect();
ret= "ok";
}
}
}
void Application::Quit()
{
if (Close())
gSystem->ExitControl();
}
Manager *Application::DoMakeManager(Symbol type)
{
return DoMakeDocuments(type);
}
bool Application::OpenDocument(char *name)
{
bool rc= FALSE, dodelete= FALSE;
Data *data;
Manager *mp;
if (name == 0) {
if (fileDialog == 0)
fileDialog= MakeFileDialog();
if (fileDialog->ShowInWindow(eFDRead, 0, this) != cIdOk)
return FALSE;
name= fileDialog->FileName();
data= fileDialog->GetData();
} else {
data= new FileData(name);
dodelete= TRUE;
}
if (!CanOpen(data)) {
ShowAlert(eAlertNote, "cannot handle document @I%s@P (%s)\n",
data->FullName(), data->Type().AsString());
} else {
mp= DoMakeManager(data->Type()); // let user make his managers
if (mp) {
AddManager(mp);
mp->Show();
((Document*)mp)->LoadData(data, TRUE);
gWindowSystem->Update();
rc= TRUE;
}
}
if (dodelete)
delete data;
return rc;
}
bool Application::CanOpen(Data *data)
{
if (mainDocumentType == cDocTypeUndef || mainDocumentType == data->Type())
return TRUE;
if (mainDocumentType == cDocTypeAscii && data->IsAscii())
return TRUE;
return FALSE;
}
void Application::MakeInitManager()
{
if (Size() <= 0)
NewManager(mainDocumentType);
}
int Application::Run()
{
gRpc= new AppRpcConnection;
gClipBoard= new ClipBoard;
gProgress= new ProgressImpl;
gSystem->AddSignalHandler(new ApplIntHandler);
ParseCommandLine(gArgc, gArgv);
MakeInitManager();
Open();
gSystem->Control();
SetErrorHandler(DefaultErrorHandler);
SafeDelete(gClipBoard);
SafeDelete(gRpc);
SafeDelete(gProgress);
return 0;
}
void Application::DoOnError(int level, char *location, char *msg)
{
static bool inError= FALSE;
if (level < Env::GetValue("System.IgnoreLevel", cError) || inError)
return;
inError= TRUE;
char *type= "Warning";
if (level >= cFatal)
type= "Fatal";
else if (level >= cSysError)
type= "SysError";
else if (level >= cError)
type= "Error";
cerr.form("%s: %s in <%s>: %s\n", ProgramName(), type, location, msg);
if (level >= cError) {
int r= ShowAlert(eAlertError, "%s: %s\nin @B%s@B: %s", ProgramName(),
type, location, msg);
switch (r) {
case cIdIgnore:
break;
case cIdAbort:
gSystem->Abort();
case cIdInspect:
DebuggerIF *dbg= new DebuggerIF;
dbg->Attach(gProgPath, gSystem->GetPid());
delete dbg;
//gSystem->Wait(15000);
//ShowAlert(eAlertError, "%s: Could not attach to debugger\n", ProgramName());
//Inspect();
break;
}
}
inError= FALSE;
}
//---- obsolete ----------------------------------------------------------------
Document *Application::FindDocument(int id)
{
return (Document*) Application::FindManager(id);
}
Document *Application::DoMakeDocuments(Symbol)
{
return 0;
}
bool Application::CloseAllDocuments()
{
return Close();
}
void Application::AddDocument(Document *dp)
{
AddManager(dp);
}
void Application::RemoveDocument(Document *mp)
{
RemoveManager(mp);
}
void Application::NewDocument(Symbol)
{
}
Point Application::GetNewDocumentPos()
{
Point p= lastWindowPos;
lastWindowPos+= Point(40, 30);
return p;
}
//---- external calls of ET++PE ------------------------------------------------
extern "C" int ETPE_Enter(Object *op);
static int CallCount= 0;
int ETPE_Enter(Object *op)
{
int level= CallCount++;
Port *p= GrGetPort();
if (op == 0)
op= gApplication;
if (!ObjectTable::PtrIsValid(op)) {
fprintf(stderr, "ET++PE: 0x%x is not an instance of Object\n", (int)op);
return 0;
}
op->Inspect();
//---- nested event-loop
while (CallCount > level && !gQuitApp)
gSystem->InnerLoop();
if (gQuitApp)
CallCount= 0;
fprintf(stderr, "\nETPE: Exit\n");
GrSetPort(p);
return level;
}
int gCallCount(int d)
{
CallCount+= d;
return CallCount;
}